<template>
    <div class="contentview">
        <div class="canvashead">
            <!-- <div class="gobackinfo">
                <i class="el-icon-arrow-left" @click="goback"></i>
                <span v-if="!showUpdateInput">{{ boardInfo.name }}</span>
                <input type="text" class="updnameipt" v-model="newBardName" v-if="showUpdateInput"
                    @keyup.enter="resetRrename" />
                <i class="iconfont icon-bianji1" @click="updateNameHandle"></i>
            </div> -->
            <div class="cardbtnview">
                <div class="cardaddbtnitem">
                    <div class="iconbutton">
                        <i class="iconfont icon-BasicIcons-all-"></i>
                        <p>文字</p>
                    </div>
                    <div class="cardChiadView">
                        <div class="cardaddbtnitem" @click="addCardModel('SingleText')">
                            <i class="iconfont icon-biaotilan"></i>
                            <p>标题</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Context')">
                            <i class="iconfont icon-fuwenbenkuang"></i>
                            <p>文本</p>
                        </div>
                    </div>
                </div>
                <div class="cardaddbtnitem">
                    <div class="iconbutton">
                        <i class="iconfont icon-RectangleCopy"></i>
                        <p>功能</p>
                    </div>
                    <div class="cardChiadView">
                        <div class="cardaddbtnitem" @click="addCardModel('Time')">
                            <i class="iconfont icon-shijian-xianxing"></i>
                            <p>时间</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('TabSwitch')">
                            <i class="iconfont icon-anniuzu"></i>
                            <p>切换</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('DateSearch')">
                            <i class="iconfont icon-ico_shujuchaxunyutongji_yuyueqingkuangchaxun"></i>
                            <p>日期查询</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Figure')">
                            <i class="iconfont icon-tuxingtuxiangchuli"></i>
                            <p>图形</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('LineFigure')">
                            <i class="iconfont icon-zhixian"></i>
                            <p>线条</p>
                        </div>
                    </div>
                </div>
                <div class="cardaddbtnitem">
                    <div class="iconbutton">
                        <i class="iconfont icon-tubiao"></i>
                        <p>图表</p>
                    </div>
                    <div class="cardChiadView">
                        <div class="cardaddbtnitem" @click="addCardModel('LineBarMixin')">
                            <i class="iconfont icon-trend"></i>
                            <p>折柱图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Bar')">
                            <i class="iconfont icon-tubiao"></i>
                            <p>柱状图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Grid3D')">
                            <i class="iconfont icon-zhexiantu"></i>
                            <p>三维折线图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Candlestick')">
                            <i class="iconfont icon-Kxiantu"></i>
                            <p>箱线图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Gantetu')">
                            <i class="iconfont icon-paichangantetu"></i>
                            <p>甘特图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Radar')">
                            <i class="iconfont icon-leidatu"></i>
                            <p>雷达图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('CardTable')">
                            <i class="iconfont icon-biaoge"></i>
                            <p>表格</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Element')">
                            <i class="iconfont icon-wodexiangmu"></i>
                            <p>要素</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Pie')">
                            <i class="iconfont icon-jurassic_pie-chart"></i>
                            <p>饼状图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Scatter')">
                            <i class="iconfont icon-sandiantu"></i>
                            <p>散点图</p>
                        </div>
                    </div>
                </div>
                <div class="cardaddbtnitem">
                    <div class="iconbutton">
                        <i class="iconfont icon-zhibiao1"></i>
                        <p>指标</p>
                    </div>
                    <div class="cardChiadView">
                        <div class="cardaddbtnitem" @click="addCardModel('Card')">
                            <i class="iconfont icon-tubiao-qiapian"></i>
                            <p>卡片</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Status')">
                            <i class="iconfont icon-zhuangtai"></i>
                            <p>状态图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('StatusGroup')">
                            <i class="iconfont icon-jiankongbaojing"></i>
                            <p>状态组合</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Rate')">
                            <i class="iconfont icon-bingtu1"></i>
                            <p>百分比图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('LiquidFill')">
                            <i class="iconfont icon-shuiwei"></i>
                            <p>水位图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Progress')">
                            <i class="iconfont icon-jindutiao"></i>
                            <p>进度条</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('Gauge')">
                            <i class="iconfont icon-yibiaopan"></i>
                            <p>状态仪表盘</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('NewGauge')">
                            <i class="iconfont icon-yibiaopan"></i>
                            <p>仪表盘</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('TimeOut')">
                            <i class="iconfont icon-040shalou"></i>
                            <p>倒计时</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('TimeSpeed')">
                            <i class="iconfont icon-shijian-xianxing"></i>
                            <p>时间进度</p>
                        </div>
                    </div>
                </div>
                <div class="cardaddbtnitem">
                    <div class="iconbutton">
                        <i class="iconfont icon-gonggong-wenjian"></i>
                        <p>资源</p>
                    </div>
                    <div class="cardChiadView">
                        <div class="cardaddbtnitem" @click="addCardModel('CardImg')">
                            <i class="iconfont icon-tupian1"></i>
                            <p>图片</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('VideoPlay')">
                            <i class="iconfont icon-shipin1"></i>
                            <p>视频</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('FileData')">
                            <i class="iconfont icon-gonggong-wenjian"></i>
                            <p>文件</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('TableFile')">
                            <i class="iconfont icon-72zhuangjimoban"></i>
                            <p>表格资源</p>
                        </div>
                    </div>
                </div>
                <div class="cardaddbtnitem" @click="addCardModel('Camera')">
                    <div class="iconbutton">
                        <i class="iconfont icon-video-camera"></i>
                        <p>摄像头</p>
                    </div>
                </div>
                <div class="cardaddbtnitem" @click="addCardModel('Submit')">
                    <div class="iconbutton">
                        <i class="iconfont icon-0-48"></i>
                        <p>提交</p>
                    </div>
                </div>
                <div class="cardaddbtnitem" @click="addCardModel('Embed')">
                    <div class="iconbutton">
                        <i class="iconfont icon-lianjie"></i>
                        <p>嵌入</p>
                    </div>
                </div>
                <div class="cardaddbtnitem">
                    <div class="iconbutton">
                        <i class="iconfont icon-ditu"></i>
                        <p>地图</p>
                    </div>
                    <div class="cardChiadView">
                        <div class="cardaddbtnitem" @click="addCardModel('NewMap')">
                            <i class="iconfont icon-dituleiditu"></i>
                            <p>跳转地图</p>
                        </div>
                        <div class="cardaddbtnitem" @click="addCardModel('NewMap2')">
                            <i class="iconfont icon-ditu1"></i>
                            <p>菜单地图</p>
                        </div>
                    </div>
                </div>
            </div>
            <el-row :gutter="20">
                <el-col :span="6">
                    <el-tooltip effect="dark" placement="bottom">
                        <i class="shortcurinfo iconfont icon-shortcut"></i>
                        <div slot="content">
                            <div style="font-size:15px;">
                                编辑模板快捷键：<br>全选&nbsp;&nbsp;&nbsp;Ctrl+A<br>多选
                                长按Shift+点击<br>复制&nbsp;&nbsp;&nbsp;Ctrl+C<br>粘贴&nbsp;&nbsp;&nbsp;Ctrl+V<br>删除&nbsp;&nbsp;&nbsp;Delete<br>撤回&nbsp;&nbsp;&nbsp;Ctrl+Z
                            </div>
                        </div>
                    </el-tooltip>
                </el-col>
                <el-col :span="9">
                    <el-button @click="onSubmit" v-loading.fullscreen.lock="fullscreenLoading" :disabled="!isUpdateData"
                        size="small">保存</el-button>
                </el-col>
                <el-col :span="9">
                    <el-button @click="showView()" type="primary" size="small">预览</el-button>
                </el-col>
            </el-row>
        </div>
        <div class="editercontent">
            <div class="editerview" @click.self="clickCanvasWarp">
                <!-- 包裹层 -->
                <div ref="canvaswaper" class="canaswaper">
                    <!-- 设置放大缩小层 -->
                    <div class="scalewrpe" :style="scaleEditStyle" @click.self="clickCanvasWarp">
                        <!-- 主内容 做比例缩放 -->
                        <div class="canvasediter" ref="sliceimg" :class="backageData.templateClass" :style="canvasStyle">
                            <!-- 网格样式 -->
                            <div class="grid-container" :style="groupStyle">
                                <div v-for="(i, index) in groupSize" :key="index" :style="groupLineStyle"></div>
                            </div>
                            <div :style="backgroundStyle" style="width:100%;height:100%;">
                                <div class="drawing" @click.self="clickCanvasWarp">
                                    <vue-draggable-resizable class="cardeditview" :scale="scale"
                                        :class="{ 'draw-active-class': drage.checked }" v-for="(drage, index) in plugsData"
                                        :key="drage.id" :z="drage.style.zIndex" :parent="false" :x="drage.style.left"
                                        :y="drage.style.top" :w="drage.style.width" :h="drage.style.height"
                                        :draggable="!drage.draggable" @activated="onActivated(drage, index)"
                                        v-show="switchCardTab(drage)"
                                        @dragging="(left, top) => onDrag(drage, key, left, top)"
                                        @dragstop="(left, top) => onDragStop(drage, key, left, top)"
                                        @resizing="(left, top, width, height) => onResize(drage, key, left, top, width, height)"
                                        @resizestop="(left, top, width, height) => onResizeStop(drage, key, left, top, width, height)">
                                        <component :is="drage.type" :ref="'ref_' + drage.id" :obj="drage" :isEdit="true"
                                            :getTableValue="getTableValue" @tabHideCardHandle="tabHideCardHandle"
                                            @dateSearchHandle="dateSearchHandle" />
                                    </vue-draggable-resizable>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="edit-style">
                <SetingForm v-show="editFormShowType == 0" v-model="backageData" @setTemplate="setTemplate"
                    :predefineColors="predefineColors" @replaceAllBackground="replaceAllCardBg" ref="a123" />
                <FormModel v-show="editFormShowType == 1" v-model="activeCardObj" :isTab="istableCard"
                    :reloadRunCardData="runCardDataReload" :plugsDataArray="plugsData" />
                <!-- 多选后提示 -->
                <div v-if="selectIdArr.length > 1" style="padding:20px;">
                    <p>已选择中{{ selectIdArr.length }}个组件</p>
                    <br>
                    <p class="cardpcl">同时锁定<i class="iconfont icon-suoding1" @click="setDraggableSelectAll(true)"></i></p>
                    <p class="cardpcl"> 同时解锁<i class="iconfont icon-jiesuo" @click="setDraggableSelectAll(false)"></i></p>
                </div>
                <!-- 右上角三个图标 -->
                <div class="cardeditbtns" v-show="selectIdArr.length">
                    <template v-if="selectIdArr.length == 1">
                        <i class="iconfont icon-suoding1" v-if="activeCardObj.draggable" title="取消锁定"
                            @click="setDraggable(false)"></i>
                        <i class="iconfont icon-jiesuo" v-else title="锁定" @click="setDraggable(true)"></i>
                    </template>
                    <i class="iconfont icon-fuzhi" title="复制" @click="copyCardHandle()"></i>
                    <i class="iconfont icon-guanbi" title="删除" @click="deleteCardHandle()"></i>
                </div>
            </div>
        </div>

        <div class="console" v-if="false">
            <p>{{ backageData }}</p>
            <p>{{ plugsData }}</p>
        </div>
    </div>
</template>

<script>
// import axios from 'axios'
import VueDraggableResizable from "vue-draggable-resizable"
import 'vue-draggable-resizable/dist/VueDraggableResizable.css'
import html2canvas from "html2canvas"

// import { getDetail, update, rechristen } from '@/api/board'
// import { QueryLimitOne } from '@/api/dataLoad'
// import { query as statTableQuery } from '@/api/statistics'
import { zipe, unzipe } from '@/utils'
import CanvasCardClass from "./class"
import { mapGetters } from 'vuex'
export default {
    Name: "CanvasEditer",
    props: {
        id: String
    },
    components: {
        VueDraggableResizable,
        FormModel: () => import("./components/FormModel.vue"),
        SetingForm: () => import("./components/SetingForm.vue"),
        SingleText: () => import("./type/SingleText.vue"),
        Context: () => import("./type/Context.vue"),
        // CardTable: () => import("./type/CardTable.vue"),
        Time: () => import("./type/Time.vue"),
        Card: () => import("./type/Card.vue"),
        Rate: () => import("./type/Rate.vue"),
        Pie: () => import("./type/Pie.vue"),
        Bar: () => import("./type/Bar.vue"),
        CardImg: () => import("./type/CardImg.vue"),
        // LiquidFill: () => import("./type/LiquidFill.vue"),
        Progress: () => import("./type/Progress.vue"),
        Gauge: () => import("./type/Gauge.vue"),
        NewGauge: () => import("./type/NewGauge.vue"),
        VideoPlay: () => import("./type/VideoPlay.vue"),
        Embed: () => import("./type/Embed.vue"),
        Submit: () => import("./type/Submit.vue"),
        Status: () => import("./type/Status.vue"),
        FileData: () => import("./type/File.vue"),
        LineBarMixin: () => import("./type/LineBarMixin.vue"),
        StatusGroup: () => import("./type/StatusGroup.vue"),
        // Camera: () => import("./type/Camera.vue"),
        TimeOut: () => import("./type/TimeOut.vue"),
        TimeSpeed: () => import("./type/TimeSpeed.vue"),
        EchartMap: () => import("./type/EchartMap.vue"),
        Scatter: () => import("./type/Scatter.vue"),
        LineFigure: () => import("./type/LineFigure.vue"),
        Figure: () => import("./type/Figure.vue"),
        // NewMap: () => import("./type/NewMap.vue"),
        TableFile: () => import("./type/TableFile.vue"),
        // NewMap2: () => import("./type/NewMap2.vue"),
        TabSwitch: () => import("./type/TabSwitch.vue"),
        // DateSearch: () => import("./type/DateSearch.vue"),
        // Element: () => import("./type/Element.vue"),
        // Grid3D: () => import("./type/Grid3D.vue"),
        Radar: () => import("./type/Radar.vue"),
        Candlestick: () => import("./type/Candlestick.vue"),
        Gantetu: () => import("./type/Gantetu.vue"),
    },
    data() {
        return {
            // 缩放看板画笔比例 默认1:1
            scale: 1,
            istableCard: 0,
            boardInfo: {},
            // 提交loadding
            fullscreenLoading: false,
            isResizeStop: false,
            // 显示模块的编辑页面
            // 显示右侧编辑内容
            editFormShowType: 0,
            // activeEditShow: false,
            // 被编辑的模块json对象
            activeCardObj: {},
            activeCardIndex: 0,
            // 宽高打折率 用于等比例展示
            discount: 0,
            // 计算用的基础属性
            baseParam: {
                screenWidth: 0,
                screenHeight: 0,
            },
            // 背景样式
            backgroundStyle: {
            },
            canvasStyle: {},
            canvasBorderStyle: {},
            scaleEditStyle: {},
            // 默认背景参数
            defaultStyle: {
                rightWidth: 370 + 16,
                headHeight: 60,
            },
            // 背景属性和初始值
            backageData: {
                templateClass: "month-white",
                sizeId: 1,
                width: 1920,
                height: 1080,
                backgroundColor: "",
                backgroundImage: "",
                gridLine: 12,
                gridRow: 12,
                lineWidth: 5,
                gridWidth: 0,
                gridHeight: 0,
                isSerializeBg: false,
                replaceBackgroundImage: "",
                replaceBackgroundColor: "",
                reloadTime: 600,    // 整个页面刷新时间倒计时/秒
                isHideGridLine: false,  //隐藏网格线
                // 编辑视图放大比例
                editStepVal: 1,
            },
            // 组件对象列表
            plugsData: [],
            // 判断页面是否有修改
            isUpdateData: false,
            // 分享url
            shareUrl: "",
            // 网格相关
            groupSize: 0,
            groupStyle: {},
            groupLineStyle: {},
            // 改名
            newBardName: "",
            showUpdateInput: false,
            // 选择选择
            // predefineColors: [
            //     "rgb(39, 161, 234)",
            //     "rgb(98, 213, 178)",
            //     "rgb(150, 161, 172)",
            //     "rgb(255, 193, 16)",
            //     "rgb(251, 110, 108)",
            //     "rgb(33, 194, 219)",
            //     "rgb(146, 135, 231)",
            //     "#164E72",
            //     "rgb(31, 128, 187)",
            //     "rgb(78, 170, 142)",
            //     "rgb(104, 112, 120)",
            //     "rgb(228, 163, 69)",
            //     "rgb(200, 88, 86)",
            //     "rgb(26, 155, 175)",
            //     "rgb(116, 108, 187)",
            //     "#053B59",
            //     "rgb(35, 144, 210)",
            //     "rgb(87, 191, 159)",
            //     "rgb(134, 144, 154)",
            //     "rgb(254, 182, 77)",
            //     "rgb(225, 98, 96)",
            //     "rgb(29, 174, 196)",
            //     "rgb(131, 121, 207)",
            //     "#2C6689",
            //     "rgb(82, 179, 238)",
            //     "rgb(129, 221, 193)",
            //     "rgb(181, 189, 197)",
            //     "rgb(255, 218, 67)",
            //     "rgb(251, 139, 137)",
            //     "rgb(90, 219, 239)",
            //     "rgb(167, 159, 235)",
            //     "#5683A1",
            //     "rgb(125, 198, 242)",
            //     "rgb(161, 229, 208)",
            //     "rgb(202, 208, 213)",
            //     "rgb(255, 232, 142)",
            //     "rgb(252, 168, 166)",
            //     "rgb(132, 228, 243)",
            //     "rgb(189, 183, 240)",
            //     "#93B8D2",
            //     "#ffffff",
            //     "#000000",
            //     "rgba(0, 0, 0, 0)"
            // ],
            // ctrl 是否按下
            isctrl: false,
            // ctrl + c 复制后的
            copyActiveCard: undefined,
            // delete 删除后的
            deleteActiveCard: undefined,
            // ctrl 是否按下
            isctrl: false,
            // shift是否长按
            isshift: false,
            // ctrl + c 复制后的选中的数组
            copyActiveCard: [],
            // delete 删除后的
            deleteActiveCardArray: [],
            // 多选选中的id 集合
            selectIdArr: [],
            // 数据缓存
            cardTableDataList: {},
            reloadDataTime: null,
            hideCardIds: [],
        }
    },
    created() {
        this.init();
    },
    mounted() {
        // 分享链接拼接
        this.shareUrl = window.location.origin + "/share/" + this.id;

        // 快捷键事件绑定
        window.addEventListener('keydown', this.handleEvent)
        window.addEventListener('keyup', this.handleKeyUp)

        // const app = this.$refs.canvaswaper;// document.querySelector('#test');
        // const hammertime = new Hammer(app);
        // hammertime.get('pinch').set({ enable: true });

        // var mc = new Hammer.Manager(app);
        // mc.add(new Hammer.Pinch({ threshold: 0 })).recognizeWith([mc.get('pan'), mc.get('rotate')]);
        // mc.on("pinchstart pinchmove", onPinch);

        // function onPinch(ev) {
        //   console.log(ev);
        // }

        // hammertime.on('pinch', function (ev) {
        //   console.log(ev);
        // });
    },
    beforeDestroy() {
        window.removeEventListener('keydown', this.handleEvent) // 在页面销毁的时候记得解除
        window.removeEventListener('keyup', this.handleKeyUp) // 在页面销毁的时候记得解除
    },
    computed: {
        ...mapGetters(['colorMap', 'predefineColors'])
    },
    methods: {
        // 编辑页面打开后初始化操作

        init() {
            // this.setbaseParam();

            // this.setBackageStyle();
            this.getdetail();
        },

        // #region 全局样式

        // 设置编辑看板样式【宽高、背景、网格样式】
        setBackageStyle() {
            // 获取模板样式
            var ksin = this.$store.getters.getKsinDetail(this.backageData.templateClass);
            if (ksin) {
                // 实际背景颜色变成网格线条颜色 背景色赋值到网格颜色
                var backgroundColor = ksin.background;
            } else {
                var backgroundColor = "";
            }

            var backgroundImage = "";
            var canvasWidth = this.backageData.width;
            var canvasHeight = this.backageData.height;

            if (this.backageData.backgroundImage.length) {
                backgroundImage = `url(${this.backageData.backgroundImage}`;
            } else if (this.backageData.backgroundColor.length > 0) {
                backgroundColor = this.backageData.backgroundColor;
            } else {
                this.backageData.backgroundColor = backgroundColor;
            }

            this.backgroundStyle = {
                backgroundImage,
                backgroundSize: "100% 100%",
            }
            // #region 看板编辑外层容器样式设置
            // canvaswaper
            let scaleXValue = 1;
            let scaleYValue = 1;
            let scaleOrigin = "top left";
            let wrapWidth = this.$refs.canvaswaper.offsetWidth;
            let wrapHeight = this.$refs.canvaswaper.offsetHeight;

            // 等比例缩放画布验证
            if (wrapWidth < canvasWidth || wrapHeight < canvasHeight) {
                scaleXValue = Math.floor(wrapWidth / canvasWidth * 10000) / 10000;
                scaleYValue = scaleXValue;
                // 判断高是否溢出
                if (canvasHeight > canvasWidth) {
                    // if (wrapHeight < canvasHeight * scaleXValue) {
                    scaleYValue = Math.floor(wrapHeight / canvasHeight * 10000) / 10000;
                    scaleXValue = scaleYValue;
                    scaleOrigin = "top center";
                }
            }

            this.canvasStyle = {
                width: canvasWidth + "px",
                height: canvasHeight + "px",
                backgroundColor: this.backageData.isHideGridLine ? backgroundColor : ksin.gridColor,
                transform: `scale(${scaleXValue}, ${scaleYValue})`,
                transformOrigin: scaleOrigin,
                margin: "0 auto",
            }

            // #endregion

            // #region 放大缩小视图
            if (this.backageData.editStepVal < 1) {
                this.backageData.editStepVal = 1;
            }
            this.scaleEditStyle = {
                transform: `scale(${this.backageData.editStepVal})`,
                transformOrigin: "top left",
            }

            // #endregion

            // 缩放比率编辑时调整
            // console.log("缩放比率：" + scaleXValue);
            this.scale = scaleXValue * this.backageData.editStepVal;

            // #region 网格样式计算

            // 网格和看板背景色
            this.groupLineStyle = {
                backgroundColor: backgroundColor
            }

            // this.canvasBorderStyle = {
            //   border: `solid 8px ${ksin.gridColor}`
            // }

            var shu = this.backageData.gridLine > 0 ? this.backageData.gridLine : 1;
            var heng = this.backageData.gridRow > 0 ? this.backageData.gridRow : 1;

            this.groupSize = heng * shu;

            var columns = "";
            var rows = "";
            for (var i = 0; i < heng; i++) {
                rows += "auto ";
            }
            for (var i = 0; i < shu; i++) {
                columns += "auto ";
            }

            // this.groupStyle.width = this.backageData.width + "px";
            // this.groupStyle.height = this.backageData.height + "px";
            if (backgroundImage.length) {
                this.groupStyle.opacity = .5;
            } else {
                this.groupStyle.opacity = 1;
            }
            this.groupStyle.gap = this.backageData.lineWidth + "px";
            this.groupStyle.gridTemplateColumns = columns;
            this.groupStyle.gridTemplateRows = rows;

            // 计算方格宽高
            var hangWidth = this.backageData.lineWidth * (shu - 1);
            var shuHeight = this.backageData.lineWidth * (heng - 1);

            this.backageData.gridWidth = (parseInt((canvasWidth - hangWidth) / shu * 100) / 100).toFixed(2);
            this.backageData.gridHeight = parseInt((canvasHeight - shuHeight) / heng * 100) / 100;
            // console.log((height - shuHeight) / heng);
            // #endregion
        },

        // 更换模板后重新批量设置样式
        setTemplate() {
            var ksin = this.$store.getters.getKsinDetail(this.backageData.templateClass);

            this.backageData.backgroundColor = ksin.background;
            var data = this.plugsData;
            if (data.length) {
                data.forEach(element => {
                    if (element.style) {
                        // element.style.backgroundColor = ksin.cardBackground;
                        element.style.color = ksin.color;
                    }

                    if (element.tableData) {
                        element.tableData.color = ksin.cardFontColor;
                        element.tableData.lineColor = ksin.cardLine;
                    }
                });

                this.plugsData = data;
            }

            // 更新全局样式
            this.setBackageStyle();
        },

        // #endregion

        // #region api请求

        // 提交保存看板 上传封面图
        onSubmit() {
            // 关闭掉选中状态
            this.clickCanvasWarp();

            // 判断是否存在数据如果不存在就不保存和修改
            if (this.plugsData.length) {
                this.fullscreenLoading = true;


                // 保存到本地
                var data = { "plugsData": this.plugsData, "backageData": this.backageData };
                var jsonStr = JSON.stringify(data);

                // 压缩看板内容
                var zip = zipe(jsonStr);
                sessionStorage.setItem("jsonData", zip);
                this.fullscreenLoading = false;
                this.isUpdateData = false;
                return false;

                // 1、生成封面图 2、上传图片  3、保存看板信息
                var self = this;
                this.$nextTick(() => {
                    html2canvas(self.$refs.sliceimg, {
                        // allowTaint: true,
                        useCORS: true,
                        backgroundColor: this.backageData.backgroundColor
                    }).then(canvas => {
                        let dataURL = canvas.toDataURL("image/png");

                        const filename = `${self.boardInfo.id}.png`;
                        const file = self.dataURLtoFile(dataURL, filename);

                        /*
                        //  cos上传资源
                        // uploadObject(file, (res) => {
                        //     if (res.code == 0) {
                        //         // this.headimg = res.url;
                        //         // this.dataform.img = res.url;
                        //         self.updateInfo(res.filePath);
                        //     } else {
                        //         self.$message.error(res.message);
                        //         // console.error("上传失败：" + res.data.message);
                        //         self.updateInfo("");
                        //     }
                        // })
                        */

                        /* api 图片上传
                        // var form = new FormData();
                        // var config = {
                        //     headers: { 'Content-Type': 'multipart/form-data' }
                        // }
                        // form.append('file', file);
                        // form.append('CustomerId', this.$store.getters.firmId);
                        // 上传封面图片

                        // axios.post(process.env.VUE_APP_UPLOAD_NEWAPI, form, config).then(res => {
                        //     if (res.data.code == 0) {
                        //         self.updateInfo(res.data.data);
                        //     } else {
                        //         console.error("上传失败：" + res.data.message);
                        //         self.updateInfo("");
                        //     }
                        // });
                        */
                    });
                })
            } else {
                this.updateInfo();
            }
        },
        // 提交更新看板信息
        updateInfo(srcdata) {
            this.fullscreenLoading = true;

            var data = { "plugsData": this.plugsData, "backageData": this.backageData };
            // sessionStorage.setItem("jsonData", JSON.stringify(data));


            var jsonStr = JSON.stringify(data);
            // 压缩看板内容
            var zip = zipe(jsonStr);

            // return false;
            // this.$router.push("canvas");
            // console.table(this.plugsData);

            var formData = {
                id: this.boardInfo.id,
                name: this.boardInfo.name,
                url: srcdata,
                structure: zip,
            }

            update(formData).then((res) => {
                this.fullscreenLoading = false;
                if (res.data.code == 0) {
                    this.$message({
                        message: "保存成功",
                        type: "success",
                    });

                    // 已保存后状态
                    this.isUpdateData = false;
                } else {
                    this.$message.error(res.data.msg);
                }
            }).catch(() => {
                this.fullscreenLoading = false;
            });
        },

        // 获取看板数据
        getdetail() {
            this.setBackageStyle();
            return false;
            this.fullscreenLoading = true;

            getDetail({ id: this.id }).then((res) => {
                this.fullscreenLoading = false;
                if (res.data.code == 0 && res.data.data) {
                    this.boardInfo = res.data.data;
                    if (this.boardInfo.structure) {
                        try {
                            // 解压缩数据                            
                            var jsonStr = unzipe(this.boardInfo.structure);
                            const jsonData = JSON.parse(jsonStr);

                            if (jsonData) {
                                this.backageData = jsonData.backageData;
                                this.plugsData = jsonData.plugsData;

                                // 数据缓存请求方案
                                this.runCardDataReload();
                            } else {
                                this.setBackageStyle();
                            }
                        } catch (e) {
                            this.$message.error("看板数据解析失败");
                        }
                    } else {
                        this.setBackageStyle();
                    }
                }

                this.$nextTick(() => {
                    this.isUpdateData = false;
                })
            }).catch(() => {
                this.fullscreenLoading = false;
            });
        },

        // #endregion

        // #region 组件事件
        /**
         * 批量设置背景图
         */
        replaceAllCardBg() {
            var data = this.plugsData;
            // console.log(this.backageData);
            if (this.backageData.isSerializeBg && data.length) {
                data.forEach(element => {
                    if (element.style) {
                        element.style.backgroundColor = this.backageData.replaceBackgroundColor
                        element.style.backgroundImage = this.backageData.replaceBackgroundImage;
                    }
                });
                // data.forEach(element => {
                //     if (element.style) {
                //         element.style.backgroundImage = this.backageData.replaceBackgroundImage;
                //     }
                // });
                this.plugsData = data;
            }
        },
        // 修改名称
        updateNameHandle() {
            this.showUpdateInput = true;
            this.newBardName = this.boardInfo.name;
        },
        resetRrename() {
            if (this.newBardName.length) {
                rechristen({ id: this.boardInfo.id, newName: this.newBardName })
                    .then(() => {
                        this.$message({
                            message: "修改成功",
                            type: "success",
                        });
                        this.boardInfo.name = this.newBardName;
                        this.showUpdateInput = false;
                    })
            } else {
                this.$message.error("名称不能为空");
            }
        },
        // 查看看板详情
        showView() {
            // this.$router.push({ path: "/canvas", query: { id: this.id, showtitle: 1 }, })
            this.$router.push({ path: "/console" });
        },
        //拖拽事件
        onDrag(drage, index, left, top) {
            this.isResizeStop = true;
            // #region 批量移动选中所有组件
            // 计算出当前组件移动的位置
            var moveX = left - drage.style.left;
            var moveY = top - drage.style.top;

            for (var i = 0; i < this.plugsData.length; i++) {
                var info = this.plugsData[i];
                var idIndex = this.selectIdArr.indexOf(info.id);
                if (idIndex > -1 && info.id != drage.id && !info.draggable) {
                    info.style.left += moveX;
                    info.style.top += moveY;
                }
            }
            // #endregion 

            // 当前组件位置保存
            drage.style.left = left;
            drage.style.top = top;

            // this.plugsData[index] = drage;
            // this.activeCardObj = drage;

            // if (this.plugsData.length > 1) {
            //     // 判断是否碰住其他相同层级
            //     this.plugsData.forEach(item => {
            //         if (item.style.zIndex == drage.style.zIndex && item.id != drage.id) {
            //             if ((drage.style.left + drage.style.width) > item.style.left && drage.style.left < (item.style.left + item.style.width)) {
            //                 // 向上
            //                 if (parentTop >= drage.style.top) {
            //                     // 碰到物体底部了
            //                     if (drage.style.top <= (item.style.height + item.style.top)) {
            //                         drage.style.top = this.deComputedDiscount(item.style.height + item.style.top);
            //                         console.log("头碰到了底部")
            //                     }
            //                 } else {
            //                     // 向下移动
            //                     if (item.style.top <= (drage.style.height + drage.style.top)) {
            //                         drage.style.top = this.deComputedDiscount(item.style.top - drage.style.height);
            //                         console.log("底部碰到头")
            //                     }
            //                 }
            //             }
            //         }
            //     })
            // }
            // drage.style.left = left;
            // drage.style.top = top;

            // if (drage.style.left < this.backageData.gridRow) {
            //     drage.style.left = 0;
            // }
            // if (drage.style.top < this.backageData.gridLine) {
            //     drage.style.top = 0;
            // }
        },
        onDragStop: function (drage, index, left, top) {
            // 获取列的线数量
            var lineSize = parseInt(left / (Number(this.backageData.gridWidth) + this.backageData.lineWidth));
            var rowSize = parseInt(top / (Number(this.backageData.gridHeight) + this.backageData.lineWidth));

            // console.error(lineSize + " ------- " + this.backageData.lineWidth);

            // 获取行的线数量
            var lCeil = parseInt(left % (Number(this.backageData.gridWidth) + this.backageData.lineWidth));
            var tCeil = parseInt(top % (Number(this.backageData.gridHeight) + this.backageData.lineWidth));

            // console.error(lCeil);
            if (this.backageData.lineWidth && this.backageData.gridWidth && this.backageData.gridHeight) {
                // if (lCeil > 0) {
                //     if (drage.style.left + drage.style.width + 5 < this.backageData.width) {
                //         if (lCeil > this.backageData.gridWidth / 2) {
                //             drage.style.left = this.deComputedDiscount(this.backageData.gridWidth * (lineSize + 1) + (lineSize + 1) * this.backageData.lineWidth);
                //         } else {
                //             drage.style.left = this.deComputedDiscount(left - lCeil);

                // if (lCeil > 0) {
                if (drage.style.left + drage.style.width + 5 < this.backageData.width) {
                    if (lCeil > this.backageData.gridWidth / 2) {
                        drage.style.left = this.backageData.gridWidth * (lineSize + 1) + (lineSize + 1) * this.backageData.lineWidth;
                        // if (drage.style.left >= this.backageData.width - drage.style.width) {
                        //     drage.style.left = this.backageData.width - drage.style.width;
                        // }
                    } else {
                        // drage.style.left = this.deComputedDiscount(left - lCeil);
                        drage.style.left = this.backageData.gridWidth * lineSize + lineSize * this.backageData.lineWidth;
                    }
                } else {
                    drage.style.left = this.backageData.width - drage.style.width;
                }



                // }
                // if (tCeil > 0) {
                if (drage.style.top + drage.style.height + 5 < this.backageData.height) {
                    if (tCeil > this.backageData.gridHeight / 2) {
                        drage.style.top = this.backageData.gridHeight * (rowSize + 1) + (rowSize + 1) * this.backageData.lineWidth;
                        // if (drage.style.top >= this.backageData.height - drage.style.height) {
                        //     drage.style.top = this.backageData.height - drage.style.height;
                        // }
                    } else {
                        // drage.style.top = this.deComputedDiscount(top - tCeil);
                        drage.style.top = this.backageData.gridHeight * rowSize + rowSize * this.backageData.lineWidth;
                    }
                } else {
                    drage.style.top = this.backageData.height - drage.style.height;
                }

                if (drage.style.left < 0) {
                    drage.style.left = 0;
                }
                if (drage.style.top < 0) {
                    drage.style.top = 0;
                }
                // }
            }

            // #region 批量移动选中所有组件
            for (var i = 0; i < this.plugsData.length; i++) {
                var info = this.plugsData[i];
                var idIndex = this.selectIdArr.indexOf(info.id);
                if (idIndex > -1 && info.id != drage.id && !info.draggable) {
                    this.dragPositionSeting(info);
                }
            }
            // #endregion 

            // 根据变量解决bug
            var self = this;
            setTimeout(function () {
                self.isResizeStop = false;
            }, 100)
        },

        // 计算组件吸附效果
        dragPositionSeting(drage) {
            var left = drage.style.left;
            var top = drage.style.top;

            // 获取列的线数量
            var lineSize = parseInt(left / (Number(this.backageData.gridWidth) + this.backageData.lineWidth));
            var rowSize = parseInt(top / (Number(this.backageData.gridHeight) + this.backageData.lineWidth));

            // console.error(lineSize + " ------- " + this.backageData.lineWidth);

            // 获取行的线数量
            var lCeil = parseInt(left % (Number(this.backageData.gridWidth) + this.backageData.lineWidth));
            var tCeil = parseInt(top % (Number(this.backageData.gridHeight) + this.backageData.lineWidth));

            // console.error(lCeil);
            if (this.backageData.lineWidth && this.backageData.gridWidth && this.backageData.gridHeight) {
                // if (lCeil > 0) {
                //     if (drage.style.left + drage.style.width + 5 < this.backageData.width) {
                //         if (lCeil > this.backageData.gridWidth / 2) {
                //             drage.style.left = this.deComputedDiscount(this.backageData.gridWidth * (lineSize + 1) + (lineSize + 1) * this.backageData.lineWidth);
                //         } else {
                //             drage.style.left = this.deComputedDiscount(left - lCeil);

                // if (lCeil > 0) {
                if (drage.style.left + drage.style.width + 5 < this.backageData.width) {
                    if (lCeil > this.backageData.gridWidth / 2) {
                        drage.style.left = this.backageData.gridWidth * (lineSize + 1) + (lineSize + 1) * this.backageData.lineWidth;
                        // if (drage.style.left >= this.backageData.width - drage.style.width) {
                        //     drage.style.left = this.backageData.width - drage.style.width;
                        // }
                    } else {
                        // drage.style.left = this.deComputedDiscount(left - lCeil);
                        drage.style.left = this.backageData.gridWidth * lineSize + lineSize * this.backageData.lineWidth;
                    }
                } else {
                    drage.style.left = this.backageData.width - drage.style.width;
                }
                // }
                // if (tCeil > 0) {
                if (drage.style.top + drage.style.height + 5 < this.backageData.height) {
                    if (tCeil > this.backageData.gridHeight / 2) {
                        drage.style.top = this.backageData.gridHeight * (rowSize + 1) + (rowSize + 1) * this.backageData.lineWidth;
                        // if (drage.style.top >= this.backageData.height - drage.style.height) {
                        //     drage.style.top = this.backageData.height - drage.style.height;
                        // }
                    } else {
                        // drage.style.top = this.deComputedDiscount(top - tCeil);
                        drage.style.top = this.backageData.gridHeight * rowSize + rowSize * this.backageData.lineWidth;
                    }
                } else {
                    drage.style.top = this.backageData.height - drage.style.height;
                }
                // }
                if (drage.style.left < 0) {
                    drage.style.left = 0;
                }
                if (drage.style.top < 0) {
                    drage.style.top = 0;
                }
            }
        },

        // 设置大小
        onResize(drage, index, left, top, width, height) {
            this.isResizeStop = true;

            drage.style.width = width;
            drage.style.height = height;

            this.plugsData[index] = drage;
            this.activeCardObj = drage;
        },
        onResizeStop(drage, index, left, top, width, height) {
            // 吸附效果计算
            var lineSize = parseInt(width / (Number(this.backageData.gridWidth) + this.backageData.lineWidth));
            var rowSize = parseInt(height / (Number(this.backageData.gridHeight) + this.backageData.lineWidth));

            // console.error(lineSize + " ------- " + this.backageData.lineWidth);

            // 获取行的线数量
            var wCeil = parseInt(width % (Number(this.backageData.gridWidth) + this.backageData.lineWidth));
            var hCeil = parseInt(height % (Number(this.backageData.gridHeight) + this.backageData.lineWidth));
            if (this.backageData.lineWidth && this.backageData.gridWidth && this.backageData.gridHeight) {
                if (wCeil > 0) {
                    if (width < this.backageData.width) {
                        if (wCeil > this.backageData.gridWidth / 2) {
                            drage.style.width = this.backageData.gridWidth * (lineSize + 1) + lineSize * this.backageData.lineWidth;

                        } else {
                            if (width <= this.backageData.gridWidth && lineSize == 0) {
                                drage.style.width = this.backageData.gridWidth;
                            } else {
                                drage.style.width = this.backageData.gridWidth * lineSize + (lineSize - 1) * this.backageData.lineWidth;
                            }
                        }
                    } else {
                        // 撑满全屏宽
                        drage.style.width = this.backageData.width;
                    }
                }

                if (hCeil > 0) {
                    if (height < this.backageData.height) {
                        if (hCeil > this.backageData.gridHeight / 2) {
                            drage.style.height = this.backageData.gridHeight * (rowSize + 1) + rowSize * this.backageData.lineWidth;
                        } else {
                            if (height <= this.backageData.gridHeight && rowSize == 0) {
                                drage.style.height = this.backageData.gridHeight;
                            } else {
                                drage.style.height = this.backageData.gridHeight * rowSize + (rowSize - 1) * this.backageData.lineWidth;
                            }
                        }
                    } else {
                        // 撑满全屏宽
                        drage.style.height = this.backageData.height;
                    }
                }
            }
            // 根据变量解决bug
            var self = this;
            setTimeout(function () {
                self.isResizeStop = false;
            }, 100)
        },
        // 点击选中模块
        onActivated(drage, index) {
            // 用于监听编辑表单编辑的更新
            // this.istableCard++;
            // this.activeEditShow = true;
            // 选中的模块
            // this.activeCardObj = drage;
            // this.activeCardIndex = index;
            if (this.isshift) {
                // console.log(this.selectIdArr);
                // 判断是否已选中 否则删除
                if (drage.checked == true) {
                    // let getLocation = this.selectIdArr.indexOf(drage.id);
                    // this.selectIdArr.splice(getLocation, 1);
                    // drage.checked = false;
                } else {
                    drage.checked = true;
                    this.selectIdArr.push(drage.id);
                }

                // 选中1个及以上 显示选中数量，隐藏编辑内容
                if (this.selectIdArr.length == 1) {
                    // 选中1个 执行默认操作
                    this.editFormShowType = 1;
                    this.istableCard++;
                } else {
                    this.editFormShowType = 2;
                }

                this.activeCardObj = drage;
                this.activeCardIndex = index;
            } else {
                // 当前已经选中
                if (drage.checked) {

                } else {
                    this.istableCard++;
                    this.editFormShowType = 1;

                    // 清空选中的所有
                    this.selectIdArr = [];
                    this.plugsData.forEach(e => {
                        e.checked = false;
                    })

                    drage.checked = true;
                    this.selectIdArr.push(drage.id);
                }

                // 兼容处理
                if (drage.tableData) {
                    if (drage.tableData.type != 1) {
                        if (drage.tableData.isOnlie == undefined) {
                            drage.tableData.isOnlie = true;
                        }
                    } else {
                        drage.tableData.isOnlie = false;
                    }
                }

                this.activeCardObj = drage;
                this.activeCardIndex = index;
            }
        },
        // 点击背景切换到全局设置
        clickCanvasWarp() {
            if (this.isResizeStop) return false;
            // this.activeEditShow = false;
            // this.istableCard = 0;
            this.editFormShowType = 0;

            // 清空选中组件
            this.activeCardObj = undefined;
            this.activeCardIndex = -1;

            this.selectIdArr = [];
            this.plugsData.forEach(e => {
                e.checked = false;
            })
        },

        // 拷贝卡片
        copyCard(index, copyData) {
            if (index < 0) {
                var odldata = copyData;
            } else {
                var odldata = this.plugsData[index];
            }

            var date = new Date();
            var newId = date.getTime() + "" + parseInt(Math.random() * 1000);
            var data = this.deepClone(odldata);

            // var zIndex = 1;
            // var lastObj = this.plugsData[this.plugsData.length - 1];
            // if (lastObj.style.zIndex > 0) {
            //     zIndex = Number(lastObj.style.zIndex) + 1;
            // } else {
            var zIndex = data.style.zIndex + 1;
            // }

            data.id = newId;
            data.style.top += 20;
            data.style.left += 20;
            data.style.zIndex = zIndex;
            data.checked = true;

            this.plugsData.push(data);
            // this.$message({
            //     message: "复制成功",
            //     type: "success",
            // });
            return newId;
        },
        // 顶部按钮菜单的操作

        // 添加组件
        addCardModel(type) {
            // 样式全局配置参数
            var ksin = this.$store.getters.getKsinDetail(this.backageData.templateClass);
            if (!ksin) {
                this.backageData.templateClass = "month-white";
                ksin = this.$store.getters.getKsinDetail("month-white");
            }

            // 设置上限 80
            if (this.plugsData.length >= 80) {
                this.$message.error("已达到可添加组件上限");
                return false;
            }

            // #region 获取时间戳id、最高zIndex
            var date = new Date();
            var newId = date.getTime() + "";
            var zIndex = 0;
            if (this.plugsData.length > 0) {
                this.plugsData.filter(x => {
                    if (x.style.zIndex > zIndex) {
                        zIndex = x.style.zIndex;
                    }
                })
            }
            zIndex++;
            // #endregion 

            var newObj = false;

            let { SignalClass, CameraClass, CardImgClass, VideoPlayClass, TabSwitchClass, TableFileClass,
                ScatterClass, TimeClass, PieClass, LineBarMixinClass, RateClass, LiquidFillClass, CardTableClass,
                EchartMapClass, NewMapClass, NewMap2Class, SubmitClass, LineFigureClass, FigureClass, CardClass,
                EmbedClass, FileDataClass, TimeOutClass, TimeSpeedClass, StatusGroupClass, StatusClass, GaugeClass, NewGaugeClass,
                ProgressClass, DateSearchClass, ElementClass, Grid3DClass, ContextClass, BarClass, RadarClass, CandlestickClass, GantetuClass } = CanvasCardClass;

            // 初始化不同组件的参数
            switch (type) {
                case "Gantetu":
                    newObj = GantetuClass(ksin);
                    break;
                case "Candlestick":
                    newObj = CandlestickClass(ksin);
                    break;
                case "Radar":
                    newObj = RadarClass(ksin);
                    break;
                case "Bar":
                    newObj = BarClass(ksin);
                    break;
                case "Grid3D":
                    newObj = Grid3DClass(ksin);
                    break;
                case "Context":
                    newObj = ContextClass(ksin);
                    break;
                case "TabSwitch":
                    newObj = TabSwitchClass(ksin);
                    break;
                case "Element":
                    newObj = ElementClass(ksin);
                    break;
                case "TableFile":
                    newObj = TableFileClass();
                    break;
                case "Scatter":
                    newObj = ScatterClass(ksin);
                    break;
                case "Pie":
                    newObj = PieClass(ksin);
                    break;
                case "LineBarMixin":
                    newObj = LineBarMixinClass(ksin);
                    break;
                case "Rate":
                    newObj = RateClass(ksin);
                    break;
                case "LiquidFill":
                    newObj = LiquidFillClass(ksin);
                    break;
                case "Progress":
                    newObj = ProgressClass(ksin);
                    break;
                case "Gauge":
                    newObj = GaugeClass(ksin);
                    break;
                case "NewGauge":
                    newObj = NewGaugeClass(ksin);
                    break;
                case "CardTable":
                    newObj = CardTableClass(ksin);
                    break;
                case "EchartMap":
                    newObj = EchartMapClass();
                    break;
                case "NewMap":
                    newObj = NewMapClass();
                    break;
                case "NewMap2":
                    newObj = NewMap2Class();
                    break;
                case "Submit":
                    newObj = SubmitClass();
                    break;
                case "CardImg":
                    newObj = CardImgClass();
                    break;
                case "Camera":
                    newObj = CameraClass();
                    break;
                case "SingleText":
                    newObj = SignalClass();
                    break;
                case "LineFigure":
                    newObj = LineFigureClass(ksin);
                    break;
                case "Figure":
                    newObj = FigureClass(ksin);
                    break;
                case "Status":
                    newObj = StatusClass(ksin);
                    //   {
                    //   name: "状态图",
                    //   title: "",
                    //   tableData: {
                    //     tableId: "",
                    //     type: 0,
                    //     lineId: "",
                    //     isShowValue: true,
                    //     isShowText: false,
                    //     isBreakLine: false,
                    //     decimal: 2,
                    //     statusList: [
                    //       {
                    //         value: 300, color: ksin.color, backgroundColor: ksin.cardBackground, valSize: 16, valColor: ksin.color, valFontWeight: '', valFontStyle: '',
                    //         text: "", textSize: 16, textColor: ksin.color, textFontWeight: '', textFontStyle: '',
                    //         backgroundImage: "",
                    //         isTwinkle: false,
                    //         bgType: 0, // 0-图片，1-图标
                    //         iconGroup: "",
                    //         iconColor: ksin.color,
                    //         isNull: false, // 是否镂空
                    //         twinkleType: 0, // 闪烁类型 0-背景、1-图形
                    //       }
                    //     ],
                    //     showType: 2,
                    //     unit: "",
                    //     unitSize: 16,
                    //     unitColor: ksin.color,
                    //     unitFontWeight: '',
                    //     unitFontStyle: '',
                    //     shanTime: 0.5,
                    //   }
                    // };
                    break;
                case "StatusGroup":
                    newObj = StatusGroupClass(ksin);
                    // {
                    //   name: "状态组合",
                    //   title: "",
                    //   tableData: {
                    //     count: 0,
                    //     tableId: "",
                    //     type: 0,
                    //     lines: 3,
                    //     rows: 4,
                    //     selectedIndex: -1,
                    //     lineWidth: 5,
                    //     defautlBGColor: ksin.cardBackground,
                    //     defaultColor: ksin.color,
                    //     startLine: "",
                    //     endLine: "",
                    //     isSerialize: false,
                    //     isReplace: false,
                    //     // 批量设置默认参数
                    //     replaceData:
                    //     {
                    //       title: "",
                    //       lineId: "",
                    //       isShowValue: true,
                    //       isShowText: false,
                    //       isBreakLine: false,
                    //       decimal: 2,
                    //       value: 0,
                    //       statusList: [
                    //         {
                    //           value: 300, color: ksin.color, backgroundColor: ksin.cardBackground, valSize: 16, valColor: ksin.color, valFontWeight: '', valFontStyle: '',
                    //           text: "", textSize: 16, textColor: ksin.color, textFontWeight: '', textFontStyle: '',
                    //           backgroundImage: "",
                    //           isTwinkle: false,
                    //           bgType: 0, // 0-图片，1-图标
                    //           iconGroup: "",
                    //           iconColor: ksin.color,
                    //           isNull: false, // 是否镂空
                    //         }
                    //       ],
                    //       showType: 2,
                    //       unit: "",
                    //       unitSize: 16,
                    //       unitColor: ksin.color,
                    //       unitFontWeight: '',
                    //       unitFontStyle: '',
                    //       style: {
                    //         fontSize: 16,
                    //         justifyContent: "center",
                    //         alignItems: "center",
                    //         borderColor: "",
                    //         borderWidth: 0,
                    //         color: ksin.color,
                    //         backgroundColor: ksin.cardBackground,
                    //         backgroundImage: "",
                    //         borderRadius: 0,
                    //         fontWeight: '',
                    //         fontStyle: '',
                    //       }
                    //     },
                    //     group: [
                    //       //     {
                    //       //     lineId: "",
                    //       //     isShowValue: true,
                    //       //     isShowText: false,
                    //       //     isBreakLine: false,
                    //       //     decimal: 2,
                    //       //     statusList: [
                    //       //         {
                    //       //             value: 300, color: ksin.color, backgroundColor: ksin.cardBackground, valSize: 16, valColor: ksin.color, valFontWeight: '', valFontStyle: '',
                    //       //             text: "", textSize: 16, textColor: ksin.color, textFontWeight: '', textFontStyle: '',
                    //       //         }
                    //       //     ],
                    //       //     showType: 2,
                    //       //     unit: "",
                    //       //     unitSize: 16,
                    //       //     unitColor: ksin.color,
                    //       //     unitFontWeight: '',
                    //       //     unitFontStyle: '',
                    //       // }
                    //     ],
                    //   }
                    // };
                    break;
                case "Card":
                    newObj = CardClass(ksin);
                    break;
                case "Time":
                    newObj = TimeClass();
                    break;
                case "DateSearch":
                    newObj = DateSearchClass();
                    break;
                case "Embed":
                    newObj = EmbedClass();
                    break;
                case "FileData":
                    newObj = FileDataClass();
                    break;
                case "VideoPlay":
                    newObj = VideoPlayClass();
                    break;
                case "TimeOut":
                    newObj = TimeOutClass(ksin);
                    break;
                case "TimeSpeed":
                    newObj = TimeSpeedClass(ksin);
                    break;
                default:
                    newObj = {}
                    break;
            }

            var obj = Object.assign({}, newObj, {
                id: newId,
                type: type,
            });
            obj.style = Object.assign({}, obj.style || {}, {
                color: ksin.color,
                zIndex: zIndex,
                // backgroundColor: ksin.cardBackground,
            });

            if (obj.tableData) {
                obj.tableData.colors = this.colorMap[0].colors;
            }

            // console.log(obj);

            // 判断全局背景设置
            if (this.backageData.isSerializeBg) {
                if (this.backageData.replaceBackgroundImage) {
                    obj.style.backgroundImage = this.backageData.replaceBackgroundImage;
                }
                if (this.backageData.replaceBackgroundColor) {
                    obj.style.backgroundColor = this.backageData.replaceBackgroundColor;
                }
            }

            if (obj.type == "StatusGroup") {
                obj.style.backgroundColor = "";
            }

            //计算top left
            // 判断滚动条
            // var wrapDom = document.querySelector(".scalewrpe");
            // alert(wrapDom.scrollTop);
            obj.style.top = this.backageData.height - obj.style.height;
            obj.style.left = this.backageData.width - obj.style.width;

            this.plugsData.push(obj);
            // 触发选中效果
            this.$nextTick(() => {
                this.onActivated(obj, this.plugsData.length - 1);
            })
        },

        goback() {
            this.$router.go(-2);
        },
        // tab组件 动态隐藏组件内容
        tabHideCardHandle(hideids, showid) {
            var arr = this.hideCardIds.concat(hideids);
            showid.forEach(id => {
                if (arr.indexOf(id + "") != -1) {
                    arr.splice(arr.indexOf(id + ""), 1);
                }
            })

            this.hideCardIds = [...new Set(arr)];
        },
        switchCardTab(drage) {
            if (this.hideCardIds.indexOf(drage.id + "") != -1) {
                return false;
            }
            return true;
        },
        // 时间筛选触主组件方法
        dateSearchHandle(beginTime, endTime, ids) {
            ids.forEach(e => {
                // 调用绑定组件刷新数据
                this.$refs['ref_' + e][0].dateSearch(beginTime, endTime);
            })
        },
        // 设置选中的组件 是否锁定移动效果
        setDraggable(bool) {
            this.$set(this.activeCardObj, 'draggable', bool);
        },
        setDraggableSelectAll(bool) {
            if (this.selectIdArr) {
                var copyDataList = this.deepClone(this.plugsData);
                for (var i = 0; i < copyDataList.length; i++) {
                    var info = copyDataList[i];
                    var idIndex = this.selectIdArr.indexOf(info.id);
                    if (idIndex > -1) {
                        this.plugsData[i].draggable = bool;
                    }
                }
                this.$message("操作成功")
            }
        },
        // #endregion

        // #region 工具函数

        // file转base64
        dataURLtoFile(dataurl, filename) {
            var arr = dataurl.split(',');
            var mime = arr[0].match(/:(.*?);/)[1];
            var bstr = atob(arr[1]);
            var n = bstr.length;
            var u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new File([u8arr], filename, { type: mime });
        },
        // #endregion

        // #region 模拟数据请求和缓存
        // 获取组件内全部的请求统计循环调用api
        runCardDataReload() {
            var cardTableDataList = {};
            clearInterval(this.reloadDataTime);
            var tableIds = [];

            if (this.plugsData.length) {
                // 循环看板组件
                this.plugsData.forEach(e => {
                    // 筛选出组件类型
                    if (["Gauge", "NewGauge", "Rate", "Card", "Status", "LiquidFill", "Progress"].indexOf(e.type) >= 0) {
                        // 判断是否绑定表格
                        if (e.tableData.tableId) {
                            // 已存在表格做合并
                            if (cardTableDataList[e.tableData.tableId]) {
                                // 判断请求时间是否最小
                                var current = cardTableDataList[e.tableData.tableId];

                                // 请求api倒计时用最小值
                                if (current.reloadTime > e.tableData.reloadTime) {
                                    current.reloadTime = e.tableData.reloadTime;
                                }
                                // 最大筛选时间范围
                                if (current.filterTimeType < e.tableData.filterTimeType) {
                                    current.filterTimeType = e.tableData.filterTimeType;
                                }
                            } else {
                                var data = {
                                    timeSpeed: (e.tableData.reloadTime ? e.tableData.reloadTime : 60) * 1,
                                    itemdata: [],
                                    listdata: [],
                                    type: e.tableData.type,
                                    filterTimeType: (e.tableData.filterTimeType ? e.tableData.filterTimeType : 15) * 1,
                                };
                                cardTableDataList[e.tableData.tableId] = data;
                                tableIds.push(e.tableData.tableId);
                            }
                        }
                    }
                })
            }

            this.cardTableDataList = cardTableDataList;
            // console.log(cardTableDataList);

            var self = this;
            var timeRecord = 0;
            if (tableIds.length) {
                // this.reloadDataTime = setInterval(function () {
                tableIds.forEach((tableId, i) => {
                    var table = cardTableDataList[tableId];
                    // if (timeRecord == 0 || (timeRecord % table.timeSpeed) == 0) {
                    self.getTableData(tableId, table.type, table.filterTimeType);
                    // }
                });
                // timeRecord++;
                // }, 1000);
            }
        },
        getTableData(tableId, type, filterTimeType) {
            var listQuery = {
                pageInfo: {
                    pageSize: 1,
                    page: 1,
                    totalCount: 0
                },
                id: tableId,
                orderBy: undefined,
                orderAsc: undefined,
                name: undefined,
                typeInc: [],
                startTime: undefined,
                beginTime: undefined,
                endTime: undefined,
                exportStartTime: undefined,
                isOnlie: true,
                cacheType: 1,
            };

            const end = new Date();
            const start = new Date();
            // 硬件表 读取缓存属性
            if (type == 0) {
                listQuery.isOnlie = true;

                // 查询一天内数据
                start.setTime(start.getTime() - 3600 * 1000 * 24);
                listQuery.beginTime = this.parseTime(start);
                listQuery.endTime = this.parseTime(end);
            } else {
                listQuery.isOnlie = false;

                start.setTime(start.getTime() - 3600 * 1000 * 24 * 365);
                listQuery.beginTime = this.parseTime(start, "{y}-{m}-{d}");
                listQuery.endTime = this.parseTime(end);
            }

            if (type == 1) {
                statTableQuery(listQuery)
                    .then((response) => {
                        if (response.data.code == 0) {
                            if (response.data.data.dataResult) {
                                var itemdata = response.data.data.dataResult.columns;
                                var listdata = response.data.data.dataResult.dataList;

                                this.cardTableDataList[tableId].itemdata = itemdata;
                                this.cardTableDataList[tableId].listdata = listdata;
                            }
                        }
                    })
            } else {
                QueryLimitOne(listQuery).then((response) => {
                    if (response.data.code == 0) {
                        if (response.data.data.dataResult) {
                            var itemdata = response.data.data.dataResult.columns;
                            var listdata = response.data.data.dataResult.dataList;

                            this.cardTableDataList[tableId].itemdata = itemdata;
                            this.cardTableDataList[tableId].listdata = listdata;
                        }
                    }
                })
            }
        },
        getTableValue(tableId, lineId, length) {
            if (this.cardTableDataList[tableId]) {
                var tableData = this.cardTableDataList[tableId];
                if (tableData.itemdata && tableData.itemdata.length && tableData.listdata && tableData.listdata.length) {

                    var itemIndex = -1;
                    tableData.itemdata.forEach((e, i) => {
                        if (e.id === lineId) {
                            itemIndex = i;
                        }
                    })

                    if (itemIndex >= 0) {
                        return { code: 200, data: tableData.listdata[0][itemIndex] };
                    }
                }
                return { code: 404, data: 0 };
            }
        },
        // #endregion

        // #region 快捷键

        handleKeyUp(event) {
            switch (event.keyCode) {
                case 16:
                    this.isshift = false;  // 如果ctrl按下就让他按下的标识符变为true
                    break;
                case 17:
                case 91:
                    this.isctrl = false;  // 如果ctrl按下就让他按下的标识符变为true
                    break;
            }
        },
        async handleEvent(event) {
            if (event.target != document.body) {
                return false;
            }
            // console.log(document.body)
            switch (event.keyCode) {
                case 16:
                    this.isshift = true;  // 如果ctrl按下就让他按下的标识符变为true
                    break;
                case 17:
                case 91:
                    this.isctrl = true;  // 如果ctrl按下就让他按下的标识符变为true
                    break;
                // 删除
                case 46:
                case 8:
                    this.deleteCardHandle();
                    break
                case 65:    // 全选
                    if (this.isctrl) {
                        this.selectIdArr = [];
                        this.plugsData.forEach(e => {
                            e.checked = true;
                            this.selectIdArr.push(e.id)
                        })

                        if (this.selectIdArr.length > 0) {
                            this.editFormShowType = 2;
                        }
                    }
                    event.preventDefault();
                    break
                // 复制
                case 67:
                    if (this.isctrl && this.selectIdArr) {
                        this.copyActiveCard = this.selectIdArr;
                    }
                    break
                // 粘贴
                case 86:
                    if (this.isctrl && this.copyActiveCard.length) {
                        this.selectIdArr = this.copyActiveCard
                        this.copyCardHandle();
                    } else {
                        this.$message("请先复制组件")
                    }
                    break
                case 90:
                    if (this.isctrl && this.deleteActiveCardArray.length) {
                        var data = this.deepClone(this.deleteActiveCardArray);
                        this.deleteActiveCardArray = [];
                        this.plugsData.push(...data);
                        // this.$message.success("恢复删除");
                    }
                    break
            }
        },
        // 批量复制
        copyCardHandle() {
            // var data = this.deepClone(this.activeCardObj);
            // this.copyCard(-1, data);

            // 被复制的需选中
            var copySelectIdArr = [];

            if (this.selectIdArr.length + this.plugsData.length > 80) {
                this.$message.error("已达到可添加组件上限");
                return false;
            }

            // 循环复制选中的
            if (this.selectIdArr) {
                var copyDataList = this.deepClone(this.plugsData);
                for (var i = 0; i < copyDataList.length; i++) {
                    var info = copyDataList[i];
                    var idIndex = this.selectIdArr.indexOf(info.id);
                    if (idIndex > -1) {
                        this.plugsData[i].checked = false;
                        var id = this.copyCard(-1, info);
                        copySelectIdArr.push(id);

                        // 删除选中数组
                        this.selectIdArr.splice(idIndex, 1);
                    }
                    if (this.selectIdArr.length <= 0) {
                        break;
                    }
                }
                this.selectIdArr = copySelectIdArr;
            }
        },
        // 批量删除
        deleteCardHandle() {
            // 循环删除选中的
            if (this.selectIdArr) {
                this.deleteActiveCardArray = [];
                var copyDataList = this.deepClone(this.plugsData);
                for (var i = copyDataList.length - 1; i >= 0; i--) {
                    var info = copyDataList[i];
                    var idIndex = this.selectIdArr.indexOf(info.id);
                    if (idIndex > -1) {
                        // 保存删除的信息
                        // info.checked = false;

                        this.deleteActiveCardArray.push(info);

                        // 删除数据
                        copyDataList.splice(i, 1);

                        // 删除选中数组
                        this.selectIdArr.splice(idIndex, 1);
                    }
                    if (this.selectIdArr.length <= 0) {
                        this.editFormShowType = 0;
                        break;
                    }
                }
                this.plugsData = copyDataList;
            }
        },

        // #endregion
    },
    watch: {
        backageData: {
            deep: true,  // 深度监听
            handler(newVal, oldVal) {
                this.isUpdateData = true;

                // this.setbaseParam();
                this.setBackageStyle();
            }
        },
        plugsData: {
            deep: true,
            handler(newVal, oldVal) {
                this.isUpdateData = true;
            }
        },
    },
    // 页面离开判断弹窗
    beforeRouteLeave(to, from, next) {
        if (this.isUpdateData) {
            const answer = window.confirm('还有未保存的操作，确认退出编辑页面吗？')
            if (answer) {
                clearInterval(this.reloadDataTime)
                clearInterval(this.time)
                next()
            } else {
                next(false)
            }
        } else {
            // 清空定时器
            clearInterval(this.reloadDataTime)
            clearInterval(this.time)
            next();
        }
    },
}
</script>
<style src="@/styles/canvasedit.css" />